{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 72,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "import numpy as np\n",
    "import matplotlib.pyplot as plt"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 73,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "X = np.empty((100,2))\n",
    "X[:,0] = np.random.uniform(0., 100, size = 100)\n",
    "X[:,1] = 0.75 * X[:,0] + 3. + np.random.normal(0., 10., size=100)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 75,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\ngg==\n",
      "text/plain": [
       "<matplotlib.figure.Figure at 0x10f379438>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "plt.scatter(X[:, 0], X[:, 1])\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# demean"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 118,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "def demean(X):\n",
    "    return X - np.mean(X, axis=0)\n",
    "\n",
    "X = demean(X)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 77,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "-8.9528384705772624e-15"
      ]
     },
     "execution_count": 77,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "np.mean(X[:, 0])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 78,
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "-8.3133500083931717e-15"
      ]
     },
     "execution_count": 78,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "np.mean(X[:, 1])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 79,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<matplotlib.figure.Figure at 0x10a97fba8>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "plt.scatter(X[:, 0], X[:, 1])\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 80,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "def f(w, X):\n",
    "    try:\n",
    "        return np.sum((X.dot(w)) ** 2) / len(X)\n",
    "    except:\n",
    "        return float('inf')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 81,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "def df_math(w, X):\n",
    "    return X.T.dot(X.dot(w)) * 2 / len(X)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 94,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "def df_debug(w, X, epsilon = 1e-4):\n",
    "    res = np.zeros(len(w))\n",
    "    \n",
    "    for i in range(len(w)):\n",
    "        w1 = w.copy()\n",
    "        w1[i] += epsilon\n",
    "        w2 = w.copy()\n",
    "        w2[i] -= epsilon\n",
    "        \n",
    "        res[i] = (f(w1, X) - f(w2, X)) / (2 * epsilon)\n",
    "        \n",
    "    return res"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 95,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "def direction(w):\n",
    "    return w / np.linalg.norm(w)\n",
    "\n",
    "def gradient_ascent(df, w, X, eta = 0.01, epsilon = 1e-6, max_iter = 1e4):\n",
    "    w = direction(w)\n",
    "    \n",
    "    cur_iter = 0\n",
    "    \n",
    "    while cur_iter < max_iter:\n",
    "        gradient = df(w, X)\n",
    "        last_w = w\n",
    "        w = w + eta * gradient\n",
    "        w = direction(w)\n",
    "        \n",
    "        if abs(f(w, X) - f(last_w, X)) < epsilon:\n",
    "            break;\n",
    "    \n",
    "        cur_iter += 1\n",
    "        \n",
    "    return w\n",
    "    "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 96,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "w = np.random.random(X.shape[1])\n",
    "w = direction(w)\n",
    "X_demean = demean(X)\n",
    "eta = 0.001\n",
    "w = gradient_ascent(df_math, w, X_demean, eta)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 97,
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([ 0.7707593 ,  0.63712644])"
      ]
     },
     "execution_count": 97,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "w"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 98,
   "metadata": {},
   "outputs": [],
   "source": [
    "w = np.random.random(X.shape[1])\n",
    "w = direction(w)\n",
    "X_demean = demean(X)\n",
    "eta = 0.001\n",
    "w = gradient_ascent(df_debug, w, X_demean, eta)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 99,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([ 0.77075286,  0.63713423])"
      ]
     },
     "execution_count": 99,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "w"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 101,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<matplotlib.figure.Figure at 0x10f611710>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "X2 = np.empty((100,2))\n",
    "X2[:,0] = np.random.uniform(0., 100, size = 100)\n",
    "X2[:,1] = 0.75 * X2[:,0] + 3.\n",
    "plt.scatter(X2[:, 0], X2[:, 1])\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 115,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "w = np.random.random(X2.shape[1])\n",
    "w = direction(w)\n",
    "X2_demean = demean(X2)\n",
    "eta = 0.001\n",
    "w = gradient_ascent(df_math, w, X2_demean, eta)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 116,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([ 0.79999615,  0.60000513])"
      ]
     },
     "execution_count": 116,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "w"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 117,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<matplotlib.figure.Figure at 0x10f1bf748>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "plt.scatter(X2_demean[:, 0], X2_demean[:, 1])\n",
    "plt.plot([0, w[0]*30], [0, w[1]*30], color='r')\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.6.3"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
